package pers.vic.system.shiro;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import pers.vic.base.bo.system.Principal;
import pers.vic.base.contant.BaseConsoleConstant;

/**
 * 表单验证过滤类
 * 
 * @author VIC
 *
 */
public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter {

	private static Logger logger = LoggerFactory.getLogger(FormAuthenticationFilter.class);
	
	public static final String DEFAULT_CAPTCHA_PARAM = "validateCode";
	public static final String DEFAULT_MESSAGE_PARAM = "message";
	public static final String DEFAULT_ForcedLogin_PARAM = "forcedLogin";
	private String captchaParam = DEFAULT_CAPTCHA_PARAM;
	private String messageParam = DEFAULT_MESSAGE_PARAM;
	private String forcedLoginParam = DEFAULT_ForcedLogin_PARAM;

	/**
	 * 可以在当中加入验证码
	 */
	protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
		/*
		 * String username = getUsername(request); String password =
		 * getPassword(request); if (password == null) { password = ""; }
		 * boolean rememberMe = isRememberMe(request); String host =
		 * CommonUtils.getRemoteIp((HttpServletRequest) request); String captcha
		 * = getCaptcha(request); boolean forcedLogin=getForcedLogin(request);
		 * UsernamePasswordToken token = new UsernamePasswordToken(username,
		 * password.toCharArray(), rememberMe, host, captcha,forcedLogin);
		 * return token;
		 */
		return super.createToken(request, response);
	}

	/**
	 * 登录成功之后跳转URL
	 */
	public String getSuccessUrl() {
		return super.getSuccessUrl();
	}
	
	
	/**
	 * 表示当访问拒绝时是否已经处理了；
	 * 如果返回true表示需要继续处理；如果返回false表示该拦截器实例已经处理了，将直接返回即可。
	 */
	@Override
	protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
		logger.info("------>----onAccessDenied------>----");
		//表示当访问拒绝时是否已经处理了；如果返回true表示需要继续处理；如果返回false表示该拦截器实例已经处理了，将直接返回即可。
		return super.onAccessDenied(request, response);
	}
	
	
	/**
	 *  判断是否登录(身份是否有效)
	 */
	@Override
	protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
		boolean isAccessAllowed = super.isAccessAllowed(request, response, mappedValue);
		logger.info("判断是否登录(身份是否有效)-->{}",isAccessAllowed);
		return isAccessAllowed;
	}

	/**
	 * 登陆成功之后
	 */
	@Override
	protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
			ServletResponse response) throws Exception {
		logger.info("------>----登陆成功------>----");
		//把用户信息放在session中 暂时用
		Principal principal = (Principal) subject.getPrincipal();
		HttpServletRequest httpServletRequest = WebUtils.toHttp(request);
        HttpSession session = httpServletRequest.getSession();
        //把用户信息保存到session
        session.setAttribute(BaseConsoleConstant.USER_SESSION_KEY, principal);
		return super.onLoginSuccess(token, subject, request, response);
	}

	/**
	 * 登录失败
	 */
	@Override
	protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request,
			ServletResponse response) {
		logger.info("------>----登录失败------>----");
		String className = e.getClass().getName(), message = "";
		if (IncorrectCredentialsException.class.getName().equals(className)
				|| UnknownAccountException.class.getName().equals(className)){
			message = "用户或密码错误, 请重试.";
		}
		else if (e.getMessage() != null && StringUtils.startsWith(e.getMessage(), "msg:")){
			message = StringUtils.replace(e.getMessage(), "msg:", "");
		}
		else{
			message = "系统出现点问题，请稍后再试！";
			logger.error(ExceptionUtils.getStackTrace(e)); // 输出到控制台
		}
        request.setAttribute(getFailureKeyAttribute(), className);
        request.setAttribute(getMessageParam(), message);
        return true;
//		return super.onLoginFailure(token, e, request, response);
	}


	protected boolean getForcedLogin(ServletRequest request) {
		return WebUtils.isTrue(request, getForcedLoginParam());
	}

	private String getForcedLoginParam() {
		return forcedLoginParam;
	}

	public String getCaptchaParam() {
		return captchaParam;
	}

	protected String getCaptcha(ServletRequest request) {
		return WebUtils.getCleanParam(request, getCaptchaParam());
	}

	public String getMessageParam() {
		return messageParam;
	}

}
